package com.ylz.sjzx.sio.room.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.ylz.sjzx.sio.common.mid.cache.redis.JedisTemplate;
import com.ylz.sjzx.sio.common.core.constant.Const;
import com.ylz.sjzx.sio.common.core.enums.Cmd;
import com.ylz.sjzx.sio.common.core.enums.MessageType;
import com.ylz.sjzx.sio.room.entity.LeaveMessageResp;
import com.ylz.sjzx.sio.room.entity.User;
import com.ylz.sjzx.sio.room.repository.SessionRepository;
import com.ylz.sjzx.sio.sdk.client.core.IMNioBase;
import com.ylz.sjzx.sio.sdk.client.engine.ChatEngine;
import com.ylz.sjzx.sio.sdk.client.engine.ChatEngineManager;
import com.ylz.sjzx.sio.sdk.client.service.IMSessionService;
import com.ylz.sjzx.sio.sdk.client.session.IMSession;
import com.ylz.sjzx.sio.sdk.client.utils.ChatRoomMessageUtil;
import com.ylz.sjzx.sio.sdk.model.BaseSocketModel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

@Slf4j
@Service()
public class IMSessionServiceImpl implements IMSessionService {


    @Value("${base.environment.value}")
    private String appEnvironment;

    @Override
    public void save(IMSession session) {
        SessionRepository.save(session);
    }

    /*
     *
     * @param account 用户id
     * @return
     */
    @Override
    public IMSession getBySid(String sid) {
        IMSession session = SessionRepository.getSid(sid);
        return session;
    }

    /*
     *
     * @param account 用户id
     * @return
     */
    @Override
    public IMSession getBySidTemp(String sid) {
        IMSession session = SessionRepository.getSidTemp(sid);
        if (session != null) {
            session.setTemState(true);
        }
        return session;
    }

    @Override
    public void removeTemp(IMSession newSession) {
        SessionRepository.removeTemp(newSession);
    }

    @Override
    public String getSidByUserId(String roomName, String userId) {
        return SessionRepository.getSidByUserId(roomName, userId);
    }

    @Override
    public IMSession getByUserId(String roomName, String userId) {
        log.debug("roomName{},userId{}", roomName, userId);
        return SessionRepository.getByUserId(roomName, userId);
    }

    @Override
    public void removeSession(IMSession session) {
        if (session == null) {
            return;
        }
        SessionRepository.remove(session);

    }

    @Override
    public void logout(String sid) {
        //登录登出一定是同一台机器  不需要考虑分布式  从进程session里面拿
        IMSession session = IMNioBase.getGlobalSession().get(sid);
        if (session == null) {
            return;
        }
        IMNioBase.getGlobalSession().remove(sid);
        IMNioBase.getSocketIOClientMap().remove(sid);
        //加锁 判断是否已经进行过登入操作 如果没有进行登录操作 那么本次登出无效
        synchronized (session.getObjectLock()) {
            if (session.getSessionState() < IMSession.STATE_CONNECT_SESSION) {
                //还未建立逻辑连接就断开
                log.info("==sid={},state={}=登出操作,未登录已经登出===连接作废", sid, session.getSessionState());
                return;

            }
        }

        //修改ImSession状态为逻辑登出状态
        session.setSessionState(IMSession.STATE_DISCONNECT_SESSION);

        //从聊天室引擎移除
        ChatEngine chatEngine = ChatEngineManager.alwaysGetChatEngine(session.getRoomName(), session.getSocketModel());
        //这边从聊天室移除chatRoomEngine
        chatEngine.removeFromChatRoomGroup(session);
        //移除基础信息
        SessionRepository.remove(session);


        User user = new User();
        user.setUserId(session.getUserId());
        //向管理组发离线消息 未来需要扩散
        LeaveMessageResp leaveMessage = LeaveMessageResp.builder().action(Cmd.leave).user(user)
                .build();
        BaseSocketModel baseSocketModel =
                BaseSocketModel.builder().action(Cmd.leave).param(BeanUtil.beanToMap(leaveMessage)).needtoParam(true)
                        .build();

        String dateTemp = JedisTemplate.me()
                .get(Const.PREFIX_YKT + "loginout:" + session.getSid());
        if (StrUtil.isBlank(dateTemp)) {
            if (Const.MKOP.equals(this.appEnvironment)) {
                //发送给所有人
                ChatRoomMessageUtil.sendMessage(session, MessageType.ALL, baseSocketModel);
            } else {
                //发送给admin
                ChatRoomMessageUtil.sendMessage(session, MessageType.ADMIN, baseSocketModel);
            }
        }


    }

    @Override
    public void saveTemp(IMSession session) {
        SessionRepository.saveTemp(session);
    }

}
